package satir;

import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;
import satir.framework.JSONIOPerformer.JSONIOPerformerException;
import satir.framework.command.RegularCommandInterpreter;
import satir.framework.command.State;
import satir.framework.packaging.Packager;
import satir.framework.packaging.Packager.PackageExtractDestinactionWriteFailure;
import satir.framework.packaging.Packager.PackagerArchieveFileDestinationNotFoundException;
import satir.framework.packaging.Packager.PackagerException;
import satir.framework.packaging.Packager.PackagerExtractAchieveFileContentInvalidException;
import satir.framework.packaging.Packager.PackagerExtractAchieveFileNotFoundException;
import satir.record.Profile;
import satir.record.SavedEntity.JSONFileInvalidException;

// TODO: Auto-generated Javadoc
/**
 * The Class SatirAnalysis.
 * @version 3.0 April 2012
 * @author Creative Family
 */
public final class SatirAnalysis {

    /** The save directory. */
    private String saveDirectory;

    /** The runtime directory. */
    private String runtimeDirectory;

    /** The profiles. */
    private Hashtable<String, Profile> profiles;

    /** The instant. */
    public static SatirAnalysis instant;

    /**
     * Instantiates a new Satir analysis.
     * @param saveDirectory
     *		the save directory
     * @param runtimeDirectory
     *		the runtime directory
     * @param configDirectory
     *		the config directory
     */
    private SatirAnalysis(final String saveDirectory, final String runtimeDirectory,
	    final String configDirectory) {
	this.saveDirectory = saveDirectory;
	this.runtimeDirectory = runtimeDirectory;
	profiles = new Hashtable<String, Profile>();
    }

    /**
     * Gets the instant.
     * @param saveDirectory
     *		the save directory
     * @param runtimeDirectory
     * 		the runtime directory
     * @param configDirectory
     * 		the config directory
     * @return the instant
     */
    public static SatirAnalysis getInstant(final String saveDirectory,
	    final String runtimeDirectory, final String configDirectory) {
	if (instant == null) {
	    instant = new SatirAnalysis(saveDirectory, runtimeDirectory,
		    configDirectory);
	}
	return instant;
    }

    /**
     * Start analyze.
     */
    public void startAnalyze() {
	// Initialize profiles
	initProfiles();
	State state = new State();
	// Execute commands
	while (state.getState() == State.STATE_PROCESSING) {
	    RegularCommandInterpreter.execute("AnalyzeCommand", state);
	}
    }

    /**
     * Gets the profile.
     * @param name
     *		the name
     * @return the profile
     */
    public Profile getProfile(final String name) {
	return profiles.get(name);
    }

    /**
     * Gets the all profiles.
     * @return the all profiles
     */
    public Hashtable<String, Profile> getAllProfiles() {
	return profiles;
    }

    /**
     * Initialize all saved profiles from repository.
     */
    private void initProfiles() {
	try {
	    extractAllProfile();
	    ArrayList<String> names = getAllProfileName();
	    for (int i = 0; i < names.size(); i++) {
		Profile profile = new Profile("Profile.json", runtimeDirectory
			+ names.get(i) + "/");
		profiles.put(names.get(i), profile);
	    }
	} catch (PackagerException e) {
	    System.out.println(e.getMessage());
	    System.exit(0);
	} catch (JSONIOPerformerException e) {
	    System.out.println(e.getMessage());
	    System.exit(0);
	} catch (JSONFileInvalidException e) {
	    System.out.println(e.getMessage());
	    System.exit(0);
	}

    }

    /**
     * Extract all profile from saveDirectory to runtimeDirectory.
     * @throws PackagerArchieveFileDestinationNotFoundException
     *             the packager archieve file destination not found exception
     * @throws PackagerExtractAchieveFileNotFoundException
     *             the packager extract achieve file not found exception
     * @throws PackagerExtractAchieveFileContentInvalidException
     *             the packager extract achieve file content invalid exception
     * @throws PackageExtractDestinactionWriteFailure
     *             the package extract destinaction write failure
     */
    private void extractAllProfile()
	    throws PackagerArchieveFileDestinationNotFoundException,
	    PackagerExtractAchieveFileNotFoundException,
	    PackagerExtractAchieveFileContentInvalidException,
	    PackageExtractDestinactionWriteFailure {
	ArrayList<String> names = getAllProfileName();
	Packager packager;
	for (int i = 0; i < names.size(); i++) {
	    String destination = runtimeDirectory + names.get(i) + "/";
	    String filename = names.get(i) + ".save";
	    packager = new Packager(filename);
	    packager.extract(saveDirectory, destination);
	}
	System.out.println();
    }

    /**
     * Retrieves all profile name from saveDirectory (e.g: save/).
     * @return the list of player profile name
     */
    public ArrayList<String> getAllProfileName() {
	ArrayList<String> profileNames = new ArrayList<String>();
	File dir = new File(saveDirectory);

	String[] children = dir.list();
	if (children != null) {
	    for (int i = 0; i < children.length; i++) {
		// Get filename of file or directory
		String filename = children[i];
		int postDot = filename.lastIndexOf(".");
		String extension = filename.substring(postDot);
		if (extension.equals(".save")) {
		    String name = filename.substring(0, postDot);
		    profileNames.add(name);
		}
	    }
	}
	return profileNames;
    }
}
